package lexer

import (
	"fmt"
	"hsql/utils"
	"strings"
)

var SqlFunctions = map[string]func(string) string{
	"AVG":   nil,
	"COUNT": nil,
}

var SqlKeywords = map[string]func(string) string{
	"AS":       nil,
	"DISTINCT": nil,
}

type Field struct {
	Name     string
	Function *SqlFunction
	Alias    string
	Distinct bool
}

func (f Field) String() string {
	sql := ""
	if f.Distinct {
		sql += "DISTINCT"
	}
	if f.Name != "" {
		sql += " " + f.Name
	} else if f.Function != nil {
		sql += " " + f.Function.String()
	}
	if f.Alias != "" {
		sql += " as " + f.Alias
	}

	return sql
}

type SqlFunction struct {
	Name string
	Expr string
}

func (f SqlFunction) String() string {
	return f.Name + "(" + f.Expr + ")"
}

func ParseFields(tokens []string) (Field, error) {
	field := Field{}
	fmt.Println(tokens)
	if len(tokens) == 1 {
		field.Name = tokens[0]
		return field, nil
	}

	pos := 0
	for pos < len(tokens) {
		token := strings.ToUpper(tokens[pos])
		sqlType, ok := utils.SqlKeywords[token]
		if !ok {
			pos++
		} else {
			switch sqlType {
			case utils.TYPE_KEYWORD:
			case utils.TYPE_FUNCTION:
				if len(tokens)-pos < 3 {
					return field, fmt.Errorf("Not a function")
				}
				pos++
				if tokens[pos] != "(" {
					return field, fmt.Errorf("Not a function")
				}
				pos++
				expr := ""
				for pos < len(tokens) {
					if tokens[pos] == ")" {
						break
					}
					expr += tokens[pos]
					pos++
				}
				function := SqlFunction{Name: token, Expr: expr}
				field.Function = &function
			case utils.TYPE_STATEMENT:
				switch token {
				case "DISTINCT":
					field.Distinct = true
				case "AS":
					if pos+2 != len(tokens) {
						return field, fmt.Errorf("expected duplicate field")
					}
					field.Alias = tokens[pos+1]
					return field, nil
				}
			default:
				pos++
			}
		}
	}

	return field, nil
}
